//============================================================================
// Name        : GA.h
// Author      : Andrey Bicalho Santos e Clayson Sandro Celes
// Version     :
// Copyright   : Your copyright notice
// Description : Genetic Algorithm in C++, Ansi-style
//============================================================================
#ifndef GA_H
#define GA_H

#include "Individual.h"

class GA{
private:
	int number_ages,current_age,k_from_tournament,
	    k_best_individuals_for_elitism,crossover_type,*k_best_index_t,
	    *mutation_rate, mutation_rate_x, mutation_rate_y,crossover_rate_x,crossover_rate_y;

	bool max_min;

	int num_individuals_population,num_genes;
	Individual *k_best_individuals_e,dad,mom,child;

public:
	GA();
	GA(int n_ag,int n_genes,int n_ind,int c_x,int c_y,int m_x, int m_y,int k_t,int k_e,int tipo);

	void pera();
	void InsertionSort(int A[],Individual pop[],int length);
	void setAge(int n);
	int getAge(void);
	int getCurrentAge(void);
	void setKfromTournamentParameter(int k);
	int getKfromTournamentParameter(void);
	void setKBestIndividualsForElitismParameter(int k);
	int getKBestIndividualsForElitismParameter(void);
	void setCrossOverType(int t);
	int getCrossOverType(void);
	void setMutationRate(int m_rate_x,int m_rate_y);
	int *getMutationRate(void);
	void setCrossOverRate(int c_rate_x,int c_rate_y);
	int *getCrossOverRate(void);
	void setNumIndividuals(int n_ind);
	int getNumIndividuals(void);

	int getHighestFitnessIndividualIndex(Individual *population);
	int getLowestFitnessIndividualIndex(Individual *population);
	double getAverageFitness(Individual *population);
	void printPopulation(Individual *population);
	void printFitnessPopulation(Individual *population);


	void TournamentSelection(Individual *pop,Individual *ind);
	void UniformCrossOver(Individual *dad_, Individual *mom_,Individual *child_);
	void OnePointCrossOver(Individual *dad_, Individual *mom_,Individual *child_);
	void TwoPointsCrossOver(Individual *dad_, Individual *mom_,Individual *child_);
	void Mutation(Individual *ind);
	void Elitism(Individual *old_pop,Individual *new_pop, Individual *k_best_elitism);
	Individual *Run(Individual *population);
	~GA();
};

#endif
